package com.bto.solar.work.service;

import cn.hutool.core.util.EnumUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.bto.solar.work.common.BizException;
import com.bto.solar.work.constant.BizStageEnum;
import com.bto.solar.work.constant.BizTaskEnum;
import com.bto.solar.work.constant.BizTaskStateEnum;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.constant.DBConstants;
import com.bto.solar.work.constant.LeaseStateEnum;
import com.bto.solar.work.dao.ILeaseReviewService;
import com.bto.solar.work.dao.IOrderBaseService;
import com.bto.solar.work.dao.IOrderStateService;
import com.bto.solar.work.dto.ApprovalReq;
import com.bto.solar.work.entity.LeaseReview;
import com.bto.solar.work.entity.OrderState;
import com.bto.solar.work.service.biz_stage_handler.StageHandlerFactory;
import com.bto.solar.work.utils.DateUtils;
import com.bto.solar.work.utils.IdUtils;
import com.bto.solar.work.utils.NullUtils;
import com.bto.solar.work.utils.StringUtils;
import com.bto.solar.work.vo.TaskCountVo;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author 王小波
 * @description:
 * @date 2023/8/16 7:58
 */

@Slf4j
@Service
public class BtoOrderStateService {
    @Autowired
    private IOrderBaseService orderBaseService;
    @Autowired
    private BtoUserService btoUserService;
    @Autowired
    private IOrderStateService orderStateService;
    @Autowired
    private StageHandlerFactory stageHandlerFactory;
    @Autowired
    private BtoOperateLogService optLog;
    @Autowired
    private ILeaseReviewService leaseReviewService;


    /**
     * 提交审批
     */
    public String updateToWaitingApprovalState(String orderId, String stageId, String taskId) {
        val handler = stageHandlerFactory.getLeaseStageHandlerByStatusId(stageId);
        handler.updateToWaitingApprovalState(orderId, stageId, taskId);
        return getOrderTaskState(orderId, stageId, taskId, true).getStateId();
    }


    /**
     * 处理审批
     */
    public String doApproval(ApprovalReq approvalReq) {
        approvalReq.setApprover(btoUserService.getCurrentUser().getUserId());
        String orderId = approvalReq.getOrderId();
        String stageId = approvalReq.getStageId();
        String taskId = approvalReq.getTaskId();
        String result = approvalReq.getResult();
        String approvalType = approvalReq.getApprovalType();
        val handler = stageHandlerFactory.getLeaseStageHandlerByStatusId(stageId);

        optLog.setApprovalInfo(approvalReq);
        if (result.contains(Constants.PASS)) {
            handler.updateToApprovalPassState(orderId, stageId, taskId, approvalType);
        } else if (result.contains(Constants.REJECT)) {
            handler.updateToApprovalRejectState(orderId, stageId, taskId, approvalType, approvalReq);
        }
        return getOrderTaskState(orderId, stageId, taskId).getStateId();
    }


    /**
     * 查询订单状态信息
     */
    public List<OrderState> getOrderStates(String orderId) {
        return orderStateService.lambdaQuery().eq(OrderState::getOrderId, orderId)
                .orderByDesc(OrderState::getCreateTime).list();
    }

    /**
     * 查询订单当前状态
     */
    public List<OrderState> getOrderCurrentStates(String orderId) {
        List<OrderState> orderStates = new ArrayList<>();
        OrderState specState = orderStateService.lambdaQuery()
                .eq(OrderState::getOrderId, orderId)
                .in(OrderState::getStateId, BizTaskStateEnum.LOCK.getStateId(),
                        BizTaskStateEnum.FINISHED.getStateId(),
                        BizTaskStateEnum.TERMINATE.getStateId())
                .one();
        if (NullUtils.isNotNull(specState)) {
            orderStates.add(specState);
            return orderStates;
        }


        List<OrderState> lastStates = orderStateService.lambdaQuery()
                .eq(OrderState::getOrderId, orderId)
                .and((wrapper) -> {
                    wrapper.like(OrderState::getStateId, "WAITING").or()
                            .like(OrderState::getStateId, Constants.REJECT);
                }).orderByDesc(OrderState::getCreateTime).list();
//        if(NullUtils.isNotEmpty(lastStates) && lastStates.get(0).getStageId().equals(BizStageEnum.CONSTRUCT.getStageId())){
//            return lastStates;
//        }
//        else if(NullUtils.isNotEmpty(lastStates)) {
//            orderStates.add(lastStates.get(0));
//            return orderStates;
//        }

//        return Collections.emptyList();
        return lastStates;
    }


    /**
     * 查询阶段-任务 数量统计
     * stageId 空 ：查询各阶段数量
     * stageId 非空 ：查询对应阶段-各任务数量
     */
    public JSONArray getStageTaskCount(String stageId) {
        JSONArray res = new JSONArray();

        //统计要排除：终结、锁定、已完成的订单
        List<String> excludeStaTes = Arrays.asList(BizTaskStateEnum.TERMINATE.getStateId(), BizTaskStateEnum.FINISHED.getStateId(), BizTaskStateEnum.LOCK.getStateId());
        List<OrderState> excludeOrders = orderStateService.lambdaQuery()
                .select(OrderState::getOrderId)
                .in(OrderState::getStateId, excludeStaTes).list();

        if (StringUtils.isEmpty(stageId)) {
            List<OrderState> stages = orderStateService.lambdaQuery()
                    .select(OrderState::getStageId)
                    .notIn(NullUtils.isNotEmpty(excludeOrders),
                            OrderState::getOrderId,
                            excludeOrders.stream().map(OrderState::getOrderId).collect(Collectors.toSet()))
                    .groupBy(OrderState::getStageId).list();
            LinkedHashMap<String, BizStageEnum> stageEnumMap = EnumUtil.getEnumMap(BizStageEnum.class);

            stages.forEach(stage -> {
                LambdaQueryWrapper<OrderState> lambdaQuery = new LambdaQueryWrapper<>();
                lambdaQuery.eq(OrderState::getStageId, stage.getStageId());
                stageEnumMap.remove(stage.getStageId());
                long count = orderStateService.count(lambdaQuery);
                JSONObject taskCountJsonObj = new JSONObject();
                taskCountJsonObj.put("stageId", stage.getStageId());
                taskCountJsonObj.put("stageName", BizStageEnum.valueOf(stage.getStageId()).getStageName());
                taskCountJsonObj.put("count", count);
                res.add(taskCountJsonObj);
            });


            stageEnumMap.forEach((key, value) -> {
                JSONObject taskCountJsonObj = new JSONObject();
                taskCountJsonObj.put("stageId", key);
                taskCountJsonObj.put("stageName", value.getStageName());
                taskCountJsonObj.put("count", 0);
                res.add(taskCountJsonObj);
            });

            return res;
        } else {
            List<OrderState> stageTasks = orderStateService.lambdaQuery()
                    .select(OrderState::getStageId, OrderState::getTaskId)
                    .notIn(NullUtils.isNotEmpty(excludeOrders),
                            OrderState::getOrderId,
                            excludeOrders.stream().map(OrderState::getOrderId).collect(Collectors.toList()))
                    .eq(OrderState::getStageId, stageId)
                    .groupBy(OrderState::getTaskId).list();

            LinkedHashMap<String, BizTaskEnum> taskEnumMap = EnumUtil.getEnumMap(BizTaskEnum.class);


            stageTasks.forEach(stageTask -> {
                LambdaQueryWrapper<OrderState> lambdaQuery = new LambdaQueryWrapper<>();
                lambdaQuery
                        .eq(OrderState::getStageId, stageTask.getStageId())
                        .eq(OrderState::getTaskId, stageTask.getTaskId());
                taskEnumMap.remove(stageTask.getTaskId());
                long count = orderStateService.count(lambdaQuery);
                JSONObject taskCountJsonObj = new JSONObject();
                taskCountJsonObj.put("taskId", stageTask.getTaskId());
                taskCountJsonObj.put("taskName", BizTaskEnum.valueOf(stageTask.getTaskId()).getTaskName());
                taskCountJsonObj.put("count", count);
                res.add(taskCountJsonObj);
            });
            taskEnumMap.forEach((key, value) -> {
                if (value.getStageEnum().getStageId().equals(stageId)) {
                    JSONObject taskCountJsonObj = new JSONObject();
                    taskCountJsonObj.put("taskId", key);
                    taskCountJsonObj.put("taskName", value.getTaskName());
                    taskCountJsonObj.put("count", 0);
                    res.add(taskCountJsonObj);
                }
            });

            return res;
//        } else {
//            List<OrderState> stageTaskStates = orderStateService.lambdaQuery()
//                    .select(OrderState::getStageId, OrderState::getTaskId, OrderState::getStateId)
//                    .notIn(NullUtils.isNotEmpty(excludeOrders),
//                            OrderState::getOrderId,
//                            excludeOrders.stream().map(OrderState::getOrderId).collect(Collectors.toList()))
//                    .eq(OrderState::getStageId, stageId)
//                    .eq(OrderState::getTaskId, taskId)
//                    .groupBy(OrderState::getStateId).list();
//
//            stageTaskStates.forEach(taskState -> {
//                LambdaQueryWrapper<OrderState> lambdaQuery = new LambdaQueryWrapper<>();
//                lambdaQuery
//                        .eq(OrderState::getStageId, taskState.getStageId())
//                        .eq(OrderState::getTaskId, taskState.getTaskId())
//                        .eq(OrderState::getStateId, taskState.getStateId());
//
//                long count = orderStateService.count(lambdaQuery);
//                JSONObject taskCountJsonObj = new JSONObject();
//                taskCountJsonObj.put("taskStateId", taskState.getStateId());
//                taskCountJsonObj.put("taskStateIdName", BizTaskStateEnum.valueOf(taskState.getStateId()).getStageName());
//                taskCountJsonObj.put("count", count);
//                res.add(taskCountJsonObj);
//
//            });
//
//            return res;
        }

    }


    public JSONArray getRejectStateCount(String stateId) {
        JSONArray res = new JSONArray();
        LambdaQueryWrapper<OrderState> orderIdsByStates = getOrderIdsByStates(null, null, stateId);
        long reject = orderStateService.count(orderIdsByStates);
        //剔除资方拒绝
        if (!BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId().equals(stateId)) {
            LambdaQueryWrapper<OrderState> lambdaQueryWrapper = getOrderIdsByStates(null, null, BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId());
            long leaseReject = orderStateService.count(lambdaQueryWrapper);
            reject = reject - leaseReject;
        }
        JSONObject taskCountJsonObj = new JSONObject();
        taskCountJsonObj.put("reject", reject);
        res.add(taskCountJsonObj);
        return res;
    }

    /**
     * 统计任务状态数量
     * stageId   对应的阶段id
     * taskId    对应的任务id
     * stateId:
     * null  任务大全 （排除-合同签约，驳回、完成）
     * WAITING_APPROVAL  审核大全
     * REJECT  内审/博通驳回
     * REJECT_LEASE  资方拨归
     */
    public JSONArray getTaskStateCount(String stageId, String taskId, String stateId) {
        JSONArray res = new JSONArray();

        //需要特殊处理的阶段  签约：全部 待签约 已签约 完成：全部 暂停中   非特殊处理的阶段：全部 待填写 待审批  通过 拒绝
        List<String> specialStage = Arrays.asList(BizStageEnum.LEASE_SIGN.getStageId(), BizStageEnum.FINISHED.getStageId());
        List<String> queryStates = Arrays.asList(BizTaskStateEnum.WAITING_FILLED.getStateId(), Constants.WAITING_APPROVAL, Constants.PASS, Constants.REJECT);
        List<String> singQueryStates = Arrays.asList(BizTaskStateEnum.WAITING_SIGN.getStateId(), BizTaskStateEnum.SIGNED.getStateId());
        List<String> finishedQueryStates = Arrays.asList(BizTaskStateEnum.FINISHED.getStateId(), BizTaskStateEnum.LOCK.getStateId());
        List<String> waitingApprovalQueryStates = Arrays.asList(Constants.WAITING_APPROVAL, Constants.PASS, Constants.REJECT);

        List<String> rejetctQueryStates = Arrays.asList(BizTaskStateEnum.APPROVAL_REJECT.getStateId(), BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId());
        List<String> rejetctLeaseQueryStates = Arrays.asList(BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId(), BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId());

        Map<String, String> viewMap = new HashMap<>();
        viewMap.put(BizTaskStateEnum.WAITING_FILLED.getStateId(), "待填写");
        viewMap.put(Constants.WAITING_APPROVAL, "待审批");
        viewMap.put(Constants.PASS, "通过");
        viewMap.put(Constants.REJECT, "拒绝");

        viewMap.put(BizTaskStateEnum.WAITING_SIGN.getStateId(), "待签约");
        viewMap.put(BizTaskStateEnum.SIGNED.getStateId(), "已签约");

        viewMap.put(BizTaskStateEnum.FINISHED.getStateId(), "已完成");
        viewMap.put(BizTaskStateEnum.LOCK.getStateId(), "已暂停");

        viewMap.put(BizTaskStateEnum.APPROVAL_REJECT.getStateId(), "内审拒绝");
        viewMap.put(BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(), "博通拒绝");
        viewMap.put(BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId(), "博通通过");


        viewMap.put(BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId(), "资方通过");
        viewMap.put(BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId(), "资方驳回");


        //统计要排除：终结、锁定、已完成的订单
        List<String> excludeStates = new ArrayList<>();
        excludeStates.add(BizTaskStateEnum.TERMINATE.getStateId());
        excludeStates.add(BizTaskStateEnum.FINISHED.getStateId());
        excludeStates.add(BizTaskStateEnum.LOCK.getStateId());

        //完成，需要查完成锁定的
        if (BizStageEnum.FINISHED.getStageId().equals(stageId)) {
            excludeStates.remove(stageId);
            excludeStates.remove(BizTaskStateEnum.LOCK.getStateId());
        }

        List<OrderState> excludeOrders = orderStateService.lambdaQuery()
                .select(OrderState::getOrderId)
                .in(OrderState::getStateId, excludeStates).list();


//        LambdaQueryChainWrapper<OrderState> stateLambdaQueryChainWrapper = orderStateService.lambdaQuery()
//                .select(OrderState::getStageId, OrderState::getTaskId)
//                .eq(StringUtils.isNotEmpty(stageId), OrderState::getStageId, stageId)
//                .eq(StringUtils.isNotEmpty(taskId), OrderState::getTaskId, taskId)
//                .groupBy(Arrays.asList(OrderState::getStageId, OrderState::getTaskId));
//
//        //task null 问题处理
//        if (StringUtils.isNotEmpty(stageId) && StringUtils.isEmpty(taskId)) {
//            stateLambdaQueryChainWrapper.isNull(OrderState::getTaskId);
//        } else {
//            stateLambdaQueryChainWrapper.eq(StringUtils.isNotEmpty(taskId), OrderState::getTaskId, taskId);
//        }
//        添加权限查询
//        List<String> userOrderIdsScoped = btoUserService.currentUserOrderIdsScoped();
//        stateLambdaQueryChainWrapper.in(NullUtils.isNotEmpty(userOrderIdsScoped),
//                OrderState::getOrderId, userOrderIdsScoped);
//
//
//        List<OrderState> stageTasks = stateLambdaQueryChainWrapper.list();


        List<String> queryStatesTemp;
        if (BizStageEnum.LEASE_SIGN.getStageId().equals(stageId)) {
            queryStatesTemp = singQueryStates;
        } else if (BizStageEnum.FINISHED.getStageId().equals(stageId)) {
            queryStatesTemp = finishedQueryStates;
        }
        //审核大全查询
        else if (Constants.WAITING_APPROVAL.equals(stateId)) {
            queryStatesTemp = waitingApprovalQueryStates;
        }
        //内审拒绝
        else if (Constants.REJECT.equals(stateId)) {
            queryStatesTemp = rejetctQueryStates;
        }
        //资方拒绝
        else if (BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId().equals(stateId)) {
            queryStatesTemp = rejetctLeaseQueryStates;
        } else {
            queryStatesTemp = queryStates;
        }

        List<String> ignoreTaskIdStage = Arrays.asList(BizStageEnum.SETTLEMENT.getStageId(), BizStageEnum.KAN_CHA.getStageId(), BizStageEnum.DESIGN.getStageId());

        queryStatesTemp.forEach(queryState -> {
            LambdaQueryWrapper<OrderState> lambdaQuery = new LambdaQueryWrapper<>();
            QueryWrapper<OrderState> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("DISTINCT order_id");
            lambdaQuery = queryWrapper.lambda();

            //权限范围内
            List<String> userOrderIdsScoped = btoUserService.currentUserOrderIdsScoped();
            if (NullUtils.isNotEmpty(userOrderIdsScoped)) {
                lambdaQuery.in(OrderState::getOrderId, userOrderIdsScoped);
            } else {
                lambdaQuery.isNull(OrderState::getOrderId);
            }

            lambdaQuery.notIn(NullUtils.isNotEmpty(excludeOrders),
                    OrderState::getOrderId,
                    excludeOrders.stream().map(OrderState::getOrderId).collect(Collectors.toSet()));

            //驳回查询，不按照阶段统计
            if (queryStatesTemp.equals(rejetctQueryStates) || queryStatesTemp.equals(rejetctLeaseQueryStates)) {
                lambdaQuery.eq(OrderState::getStateId, queryState);
                long count = orderStateService.count(lambdaQuery);
                JSONObject taskCountJsonObj = new JSONObject();
                taskCountJsonObj.put("stateId", queryState);
                taskCountJsonObj.put("stateName", viewMap.get(queryState));
                taskCountJsonObj.put("count", count);
                res.add(taskCountJsonObj);
            } else {
//                stageTasks.forEach(stageTask -> {

                LinkedHashMap<String, BizTaskStateEnum> enumMap = EnumUtil.getEnumMap(BizTaskStateEnum.class);
                lambdaQuery.and(wrapper -> {
                    if (enumMap.containsKey(queryState)) {
                        wrapper.eq(OrderState::getStateId, queryState);
                    } else {
                        wrapper.like(OrderState::getStateId, queryState);
                    }
                });
                if (StringUtils.isNotEmpty(stageId)) {
                    lambdaQuery.eq(OrderState::getStageId, stageId);
                }
                if (StringUtils.isEmpty(taskId)) {
                    if (ignoreTaskIdStage.contains(stageId)) {

                    } else {
                        lambdaQuery.isNull(OrderState::getTaskId);
                    }
                } else {
                    lambdaQuery.eq(OrderState::getTaskId, taskId);
                }

                long count = orderStateService.count(lambdaQuery);
                JSONObject taskCountJsonObj = new JSONObject();
                taskCountJsonObj.put("taskId", taskId);
                taskCountJsonObj.put("taskName", StringUtils.isNotEmpty(taskId) ? BizTaskEnum.valueOf(taskId).getTaskName() : BizStageEnum.valueOf(stageId).getStageName());
                taskCountJsonObj.put("stateId", queryState);
                taskCountJsonObj.put("stateName", viewMap.get(queryState));
                taskCountJsonObj.put("count", count);
                res.add(taskCountJsonObj);
//                });
            }
        });
        //任务大全（排除-合同签约，驳回、完成）
        if (queryStatesTemp.equals(queryStates)) {
            JSONObject taskCountJsonObjAll = new JSONObject();
            AtomicInteger allCnt = new AtomicInteger();
            res.forEach(item -> {
                Integer count = JSONObject.from(item).getInteger("count");
                allCnt.addAndGet(count);
            });
            taskCountJsonObjAll.put("taskId", taskId);
            taskCountJsonObjAll.put("taskName", StringUtils.isNotEmpty(taskId) ? BizTaskEnum.valueOf(taskId).getTaskName() : BizStageEnum.valueOf(stageId).getStageName());
            taskCountJsonObjAll.put("stateId", "");
            taskCountJsonObjAll.put("stateName", "全部");
            taskCountJsonObjAll.put("count", allCnt.get());

            res.add(0, taskCountJsonObjAll);
        }

        return res;
    }


    /**
     * 查询阶段-任务-状态 字典数据
     */
    public JSONObject getStageTaskStateDic() {
        JSONObject res = new JSONObject();
        LinkedHashMap<String, BizStageEnum> stageEnumMap = EnumUtil.getEnumMap(BizStageEnum.class);
        LinkedHashMap<String, BizTaskEnum> taskEnumMap = EnumUtil.getEnumMap(BizTaskEnum.class);
        LinkedHashMap<String, BizTaskStateEnum> stateEnumMap = EnumUtil.getEnumMap(BizTaskStateEnum.class);

        String keyStage = "stage";
        String keyTask = "task";
        String keyState = "state";
        res.put(keyStage, new JSONObject());
        res.put(keyTask, new JSONObject());
        res.put(keyState, new JSONObject());
        stageEnumMap.forEach((key, value) -> res.getJSONObject(keyStage).put(key, value.getStageName()));
        taskEnumMap.forEach((key, value) -> res.getJSONObject(keyTask).put(key, value.getTaskName()));
        stateEnumMap.forEach((key, value) -> res.getJSONObject(keyState).put(key, value.getStageName()));
        return res;
    }


    /**
     * 创建任务状态，一个任务只创建一次状态
     */
    public OrderState createOrderState(String orderId, String stageId, String taskId, String stateId) {
        synchronized (this) {
            val orgOrderState = getOrderTaskState(orderId, stageId, taskId);
            if (NullUtils.isNotNull(orgOrderState)) {
                return orgOrderState;
            }

            OrderState orderState = new OrderState();
            orderState.setId(IdUtils.fastSnowId());
            orderState.setOrderId(orderId);
            orderState.setStageId(stageId);
            orderState.setTaskId(taskId);
            orderState.setStateId(stateId);
            orderState.setCompanyId(orderBaseService.getById(orderId).getCompanyId());
            orderState.setSort(BizTaskStateEnum.valueOf(stateId).getSort());
            orderStateService.save(orderState);

            optLog.saveOrderOperateLog(orderId, stageId, taskId, stateId, stateId, null);
            return orderState;
        }
    }


    public void updateOrderTaskState(String orderId, String stageId, String taskId, String targetStateId) {
        LambdaUpdateChainWrapper<OrderState> wrapper = orderStateService.lambdaUpdate()
                .eq(OrderState::getOrderId, orderId)
                .eq(OrderState::getStageId, stageId)
                .set(OrderState::getStateId, targetStateId);
        if (StringUtils.isEmpty(taskId)) {
            wrapper.isNull(OrderState::getTaskId);
        } else {
            wrapper.eq(OrderState::getTaskId, taskId);
        }
        wrapper.update();
        optLog.saveOrderOperateLog(orderId, stageId, taskId, targetStateId, DBConstants.OPT_UPDATE, null);
    }


    public OrderState updateOrSaveOrderState(String orderId, String stageId, String taskId, String stateId, String... preStateIds) {
        for (String preStateId : preStateIds) {
            try {
                OrderState orderState = updateOrSaveOrderState(orderId, stageId, taskId, stateId, preStateId, true);
                if (NullUtils.isNotNull(orderState)) {
                    return orderState;
                }
            } catch (BizException ignored) {

            }
        }
        throw new BizException("订单 {} 阶段 {}  任务{} 更新状态 {} ，未找到必要的前状态 {}", orderId, stageId, taskId, stateId, Arrays.toString(preStateIds));
    }

    public OrderState updateOrSaveOrderState(String orderId, String stageId, String taskId, String stateId, String preStateId) {
        return updateOrSaveOrderState(orderId, stageId, taskId, stateId, preStateId, false);
    }


    public OrderState updateOrSaveOrderState(String orderId, String stageId, String taskId, String stateId, String preStateId, boolean check) {
        OrderState orderState = getOrderState(orderId, stageId, taskId, preStateId);
        //第一次填完全部必填信息，直接创建审批
        if (NullUtils.isNull(orderState)) {
            if (check) {
                log.error("订单 {} 阶段 {}  任务{} 更新状态 {} ，未找到必要的前状态 {}", orderId, stageId, taskId, stateId, preStateId);
                throw new BizException("订单 {} 阶段 {}  任务{} 更新状态 {} ，未找到必要的前状态 {}", orderId, stageId, taskId, stateId, preStateId);
            }
            createOrderState(orderId, stageId, taskId, stateId);
        } else {
            if (stateId.equals(preStateId)) {
                return orderState;
            }
            orderState.setStateId(stateId);
            orderStateService.updateById(orderState);
        }

        optLog.saveOrderOperateLog(orderId, stageId, taskId, stateId, stateId, null);

        return orderState;
    }


    public OrderState getOrderState(String orderId, String stageId, String taskId, String stateId) {
        LambdaQueryChainWrapper<OrderState> wrapper = orderStateService.lambdaQuery()
                .eq(OrderState::getOrderId, orderId)
                .eq(OrderState::getStageId, stageId);
        if (StringUtils.isEmpty(taskId)) {
            wrapper.isNull(OrderState::getTaskId);
        } else {
            wrapper.eq(OrderState::getTaskId, taskId);
        }
        wrapper.eq(OrderState::getStateId, stateId);
        return wrapper.one();
    }

    public List<OrderState> getOrderStateList(List<String> orderIds, String stageId, String taskId, String stateId) {
        LambdaQueryChainWrapper<OrderState> wrapper = orderStateService.lambdaQuery()
                .in(OrderState::getOrderId, orderIds)
                .eq(OrderState::getStageId, stageId);
        if (StringUtils.isEmpty(taskId)) {
            wrapper.isNull(OrderState::getTaskId);
        } else {
            wrapper.eq(OrderState::getTaskId, taskId);
        }
        wrapper.eq(OrderState::getStateId, stateId);
        return wrapper.list();
    }


    public List<OrderState> getOrderStateList(String stageId, String taskId, String stateId) {
        LambdaQueryChainWrapper<OrderState> wrapper = orderStateService.lambdaQuery()
                .eq(OrderState::getStageId, stageId);
        if (StringUtils.isEmpty(taskId)) {
            wrapper.isNull(OrderState::getTaskId);
        } else {
            wrapper.eq(OrderState::getTaskId, taskId);
        }
        wrapper.eq(OrderState::getStateId, stateId);
        return wrapper.list();
    }

    public List<String> getOrderStateByWaitingLeaseList() {
        //处理待越秀审核、待签约和待重新签约
        LambdaQueryChainWrapper<OrderState> wrapperByWaitLease = orderStateService.lambdaQuery()
                .eq(OrderState::getStateId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId())
                .or().eq(OrderState::getStateId, BizTaskStateEnum.WAITING_SIGN.getStateId())
                .or().eq(OrderState::getStateId, BizTaskStateEnum.WAITING_SIGN_RE.getStateId());
        List<OrderState> wrapperByWaitLeaseList = wrapperByWaitLease.list();
        List<OrderState> waitingLeaseList = new ArrayList<>();
        //去掉预审信息
        wrapperByWaitLeaseList.forEach(orderState -> {
            if (!BizTaskEnum.TASK_YSXX.getTaskId().equals(orderState.getTaskId())) {
                waitingLeaseList.add(orderState);
            }
        });
        //APPROVING
        List<LeaseReview> approvaling = leaseReviewService.lambdaQuery()
                .eq(LeaseReview::getTenantStatus, LeaseStateEnum.APPROVING).or()
                .eq(LeaseReview::getProjectStatus, LeaseStateEnum.APPROVING).or()
                .eq(LeaseReview::getFarmerSignStatus, LeaseStateEnum.APPROVING).or()
                .eq(LeaseReview::getPaymentApplyStatus, LeaseStateEnum.APPROVING).or()
                .eq(LeaseReview::getContractTextStatus, LeaseStateEnum.APPROVING).list();
        //INCEPT
        List<LeaseReview> inceptList = leaseReviewService.lambdaQuery().eq(LeaseReview::getFarmerSignStatus, LeaseStateEnum.APPROVED.getStateId())
                .isNotNull(LeaseReview::getContractStatus).list();
        List<String> result = new ArrayList<>();
        result.addAll(waitingLeaseList.stream().map(OrderState::getOrderId).collect(Collectors.toList()));
        result.addAll(inceptList.stream().map(LeaseReview::getOrderId).collect(Collectors.toList()));
        result.addAll(approvaling.stream().map(LeaseReview::getOrderId).collect(Collectors.toList()));

        return result;
    }


    public OrderState getOrderTaskState(String orderId, String stageId, String taskId, boolean check) {
        LambdaQueryChainWrapper<OrderState> wrapper = orderStateService.lambdaQuery()
                .eq(OrderState::getOrderId, orderId)
                .eq(OrderState::getStageId, stageId);
        if (StringUtils.isEmpty(taskId)) {
            wrapper.isNull(OrderState::getTaskId);
        } else {
            wrapper.eq(OrderState::getTaskId, taskId);
        }
        OrderState orderState = wrapper.one();
        if (check && NullUtils.isNull(orderState)) {
            throw new BizException("未找到 订单{} 阶段{} 任务 {} 相关的状态", orderId, stageId, taskId);
        }
        return orderState;
    }

    public OrderState getOrderTaskState(String orderId, String stageId, String taskId) {
        return getOrderTaskState(orderId, stageId, taskId, false);
    }

    /**
     * 根据状态查订单列表信息
     * 默认是去除特殊状态：完成、锁定、终结
     * 状态：
     * 支持精确匹配  -- 特定的枚举类
     * 模糊匹配  -- 待审批  拒绝
     */
    public LambdaQueryWrapper<OrderState> getOrderIdsByStates(String stageId, String taskId, String... stateIds) {
        return getOrderIdsByStates(stageId, taskId, null, stateIds);
    }

    /**
     * 根据状态查订单列表信息
     * 状态：
     * 支持精确匹配  -- 特定的枚举类
     * 模糊匹配  -- 待审批  拒绝
     */
    public LambdaQueryWrapper<OrderState> getOrderIdsByStates(String stageId, String taskId, List<String> includeSpecialStateIds, String... stateIds) {
        LambdaQueryWrapper<OrderState> orderStateQueryWrapper = new LambdaQueryWrapper<>();
        //统计要排除：终结、锁定、已完成的订单
        List<String> specStates = Arrays.asList(BizTaskStateEnum.TERMINATE.getStateId(), BizTaskStateEnum.FINISHED.getStateId(), BizTaskStateEnum.LOCK.getStateId());
        List<String> excludeStates = new ArrayList<>(specStates);
        //查询指定特殊状态，需要添加
        if (NullUtils.isNotEmpty(includeSpecialStateIds)) {
            for (String state : excludeStates) {
                if (includeSpecialStateIds.contains(state)) {
                    excludeStates.remove(state);
                }
            }
        }


        //阶段任务状态查询
        if (StringUtils.isNotEmpty(stageId)) {
            orderStateQueryWrapper.eq(OrderState::getStageId, stageId);

            List<OrderState> excludeOrders = orderStateService.lambdaQuery()
                    .select(OrderState::getOrderId)
                    .in(OrderState::getStateId, excludeStates).list();

            orderStateQueryWrapper
                    .notIn(NullUtils.isNotEmpty(excludeOrders),
                            OrderState::getOrderId,
                            excludeOrders.stream().map(OrderState::getOrderId).collect(Collectors.toSet()));
            //根据任务查询
            if (StringUtils.isNotEmpty(taskId)) {
                orderStateQueryWrapper.eq(OrderState::getTaskId, taskId);
            }
        }

        //状态枚举
        LinkedHashMap<String, BizTaskStateEnum> enumMap = EnumUtil.getEnumMap(BizTaskStateEnum.class);
        orderStateQueryWrapper.and(NullUtils.isNotEmpty(stateIds), wrapper -> {
            Arrays.stream(stateIds).forEach(stateId -> {
                if (enumMap.containsKey(stateId)) {
                    wrapper.eq(OrderState::getStateId, stateId).or();
                } else {
                    wrapper.like(OrderState::getStateId, stateId).or();
                }
            });
        });

        //添加权限查询
        List<String> userOrderIdsScoped = btoUserService.currentUserOrderIdsScoped();
        orderStateQueryWrapper.in(NullUtils.isNotEmpty(userOrderIdsScoped),
                OrderState::getOrderId, userOrderIdsScoped);

        return orderStateQueryWrapper;
    }

    public Set<String> getOrderIdsByStates(BizStageEnum excludeStage, BizTaskEnum excludeTask, List<BizTaskStateEnum> excludeStates,
                                           BizStageEnum includeStage, BizTaskEnum includeTask, List<BizTaskStateEnum> includeStates,
                                           Date startDate, Date endDate) {
        return getOrderIdsByStates(excludeStage, excludeTask, excludeStates, true, includeStage, includeTask, includeStates, startDate, endDate);
    }


    public Set<String> getOrderIdsByStates(BizStageEnum excludeStage, BizTaskEnum excludeTask, List<BizTaskStateEnum> excludeStates, boolean excludeFinished,
                                           BizStageEnum includeStage, BizTaskEnum includeTask, List<BizTaskStateEnum> includeStates,
                                           Date startDate, Date endDate) {
        LambdaQueryWrapper<OrderState> overStageLambdaQuery = new LambdaQueryWrapper<>();
        overStageLambdaQuery.select(OrderState::getOrderId);
        //需要排除的关键 阶段-任务-状态
        if (NullUtils.isNotNull(excludeStage)) {
            overStageLambdaQuery.eq(OrderState::getStageId, excludeStage.getStageId());
        }
        if (NullUtils.isNotNull(excludeTask)) {
            overStageLambdaQuery.eq(OrderState::getTaskId, excludeTask.getTaskId());
        }
        if (NullUtils.isNotEmpty(excludeStates)) {
            overStageLambdaQuery.in(OrderState::getStateId, excludeStates.stream().map(BizTaskStateEnum::getStateId).collect(Collectors.toSet()));
        }

        //排除 终止、lock、完结 订单
        List<String> defaultExcludeStates = new ArrayList<>(Arrays.asList(BizTaskStateEnum.TERMINATE.getStateId(), BizTaskStateEnum.LOCK.getStateId()));
        if (excludeFinished) {
            defaultExcludeStates.add(BizTaskStateEnum.FINISHED.getStateId());
        }
        //特殊状态的单
        overStageLambdaQuery.or()
                .in(OrderState::getStateId, defaultExcludeStates)
                //筛选时间
                .between(NullUtils.isNotNull(startDate), OrderState::getCreateTime, startDate, NullUtils.isNull(endDate) ? DateUtils.getNowDate() : endDate);
        List<OrderState> overStageOrders = orderStateService.list(overStageLambdaQuery);
        List<String> excludeOrderIds = overStageOrders.stream().map(OrderState::getOrderId).collect(Collectors.toList());


        LambdaQueryWrapper<OrderState> singedStageLambdaQuery = new LambdaQueryWrapper<>();
        singedStageLambdaQuery.select(OrderState::getOrderId)
                //需要查找的目标阶段-任务-状态
                .eq(NullUtils.isNotNull(includeStage), OrderState::getStageId, includeStage.getStageId());
        if (NullUtils.isNull(includeTask)) {
            singedStageLambdaQuery.isNull(OrderState::getTaskId);
        } else {
            singedStageLambdaQuery.eq(OrderState::getTaskId, includeTask);
        }
        //排除关键节点的订单
        List<String> includeOrderIds = btoUserService.currentUserOrderIdsScoped().stream().filter(orderId -> !excludeOrderIds.contains(orderId)).collect(Collectors.toList());
        //没有符合条件的单
        if (NullUtils.isEmpty(includeOrderIds)) {
            return Collections.emptySet();
        }
        if (NullUtils.isNotEmpty(includeStates)) {
            singedStageLambdaQuery.in(OrderState::getStateId, includeStates.stream().map(BizTaskStateEnum::getStateId).collect(Collectors.toSet()));
        }

        singedStageLambdaQuery
                .in(NullUtils.isNotEmpty(includeOrderIds), OrderState::getOrderId, includeOrderIds)
                //筛选时间
                .between(NullUtils.isNotNull(startDate), OrderState::getCreateTime, startDate, NullUtils.isNull(endDate) ? DateUtils.getNowDate() : endDate);

        List<OrderState> orderStates = orderStateService.list(singedStageLambdaQuery);
        return orderStates.stream().map(OrderState::getOrderId).collect(Collectors.toSet());
    }

    /**
     * 查询设计阶段任务状态信息
     */
    public List<TaskCountVo> getStageDesignTask() {
        JSONArray taskCountVoByCspsArray = getTaskStateCount(
                BizStageEnum.DESIGN.getStageId(),
                BizTaskEnum.TASK_CSPSXX.getTaskId(),
                Constants.WAITING_APPROVAL);
        List<TaskCountVo> taskCountVoByCspsList = JSONArray.parseArray(taskCountVoByCspsArray.toJSONString(), TaskCountVo.class);

        JSONArray taskCountVoByCspsUpdateArray = getTaskStateCount(
                BizStageEnum.DESIGN.getStageId(),
                BizTaskEnum.TASK_CSPSXX_UPDATE.getTaskId(),
                Constants.WAITING_APPROVAL);
        List<TaskCountVo> taskCountVoByCspsUpdateList = JSONArray.parseArray(taskCountVoByCspsUpdateArray.toJSONString(), TaskCountVo.class);

        for (TaskCountVo taskCountVoByCsps : taskCountVoByCspsList) {
            int count = taskCountVoByCsps.getCount();
            int countByWAIT = 0;//等待
            int countByReject = 0;//拒绝
            for (TaskCountVo taskCountVoByCspsUpdate : taskCountVoByCspsUpdateList) {
                if (Constants.WAITING_APPROVAL.equals(taskCountVoByCspsUpdate.getStateId())) {
                    countByWAIT = taskCountVoByCspsUpdate.getCount();
                    count = count + countByWAIT;
                    taskCountVoByCsps.setCount(count);
                    break;
                } else if (Constants.REJECT.equals(taskCountVoByCspsUpdate.getStateId())) {
                    countByReject = taskCountVoByCspsUpdate.getCount();
                    count = count + countByReject;
                    taskCountVoByCsps.setCount(count);
                    break;
                }
            }
            if (Constants.PASS.equals(taskCountVoByCsps.getStateId())) {
                taskCountVoByCsps.setCount(count - countByWAIT - countByReject);
            }
            taskCountVoByCsps.setTaskId(null);
        }
        return taskCountVoByCspsList;
    }


}
